#include <stdint.h>
#include <array>
#include <list>
#include <mutex>
#include <functional>
#include <memory>
#include <atomic>
using namespace std;
using TimerHandle = uint64_t;
typedef void (*cb)(void *puser);

struct TimerElem
{
    TimerHandle handle; // 新增：事件句柄（唯一标识）s
    cb callback;       // 回调函数
    void *puser;       // 用户数据
    uint64_t interval; // 周期时间（0表示一次性任务）
    bool repeat;
    uint64_t expire; // 到期时间戳
                     //  TimerElem* next;     // 链表指针
};

struct Slot
{
    std::list<TimerElem> slotelem;
    std::mutex slotelock;
};

// 抽象线程池接口：定义核心契约（仅需提交任务的能力）
class IThreadPool
{
public:
    // 虚析构：确保子类析构时能正确调用（必须）
    virtual ~IThreadPool() = default;

    // 纯虚函数：提交任务到线程池（任务类型为无参可调用对象）
    // 注：用std::function<void()>封装任意任务，保证通用性
    virtual void submit(std::function<void(void *)> task, void *puser) = 0;

    // 处理整个链表的数据，注意，此接口不能阻塞
    virtual void submit_batch(std::list<TimerElem> tasks) = 0;
};

// 方便用户使用：定义智能指针类型，避免裸指针管理
using IThreadPoolPtr = std::shared_ptr<IThreadPool>;

class ITimerDriver
{
public:
    virtual ~ITimerDriver() = default;

    // 启动驱动（开始触发时间事件）
    virtual void start() = 0;

    // 停止驱动（停止触发时间事件）
    virtual void stop() = 0;

    // 设置tick回调（时间轮的tick方法将通过此回调被触发）
    // 参数：callback - 时间到达时执行的函数（通常是时间轮的tick）
    virtual void set_tick_callback(function<void()> callback) = 0;
};
using ITimerDriverPtr = shared_ptr<ITimerDriver>;

class timers
{
private:
    std::atomic<TimerHandle> next_handle{1};
    void _calclevelandslot(uint32_t interval, uint32_t ntimeticket, int &level, int &slot);
    void _process_cycle_tasks(list<TimerElem> &cycle_tasks);
    inline void _inctimeticket();
    inline uint32_t _gettimeticket();
    uint32_t timeticket;
    std::mutex timeticketlock;

    void tick();
    std::array<std::array<Slot, 256>, 4> wheels;
    IThreadPoolPtr threadpool;

public:
    TimerHandle addtimer(cb cbs, void *puser, uint32_t interval, bool repeat);
    bool deltimer(TimerHandle handle);
    void cascade(int level, int slot);
    timers(IThreadPoolPtr ptr);
    ~timers();
};

inline void timers::_inctimeticket()
{
    std::lock_guard<std::mutex> lock(this->timeticketlock);
    ++this->timeticket;
}

inline uint32_t timers::_gettimeticket()
{
    uint32_t tmp = 0;
    std::lock_guard<std::mutex> lock(this->timeticketlock);
    tmp = this->timeticket;
    return tmp;
}

void timers::_calclevelandslot(uint32_t interval, uint32_t ntimeticket, int &level, int &slot)
{
    uint32_t expire = ntimeticket + interval;
    if (interval < 256) // 加到0层
    {
        level = 0;
        slot = (expire) % 256;
    }
    else if (interval < 256 * 256)
    {
        level = 1;
        slot = ((expire) / 256) % 256;
    }
    else if (interval < 256 * 256 * 256)
    {
        level = 2;
        slot = ((expire) / (256 * 256)) % 256;
    }
    else
    {
        level = 3;
        slot = ((expire) / (256 * 256 * 256)) % 256;
    }
}

void timers::cascade(int level, int slot)
{
    std::list<TimerElem> tmplist;
    {
        std::lock_guard<std::mutex> locks(wheels[level][slot].slotelock);
        tmplist.splice(tmplist.end(), wheels[level][slot].slotelem);
    }

    while (!tmplist.empty())
    {
        // 摘链
        TimerElem current = tmplist.front();
        tmplist.pop_front();
        int newlevel = 0;
        int newslot = 0;

        uint32_t tt = _gettimeticket();
        uint32_t remain = current.expire - tt;
        // 计算所属的层与槽
        _calclevelandslot(remain, tt, newlevel, newslot);

        {
            std::lock_guard<std::mutex> lock(wheels[newlevel][newslot].slotelock);
            wheels[newlevel][newslot].slotelem.push_back(current);
        }
    }
}

bool timers::deltimer(TimerHandle handle)
{
    if (handle == 0) {
        return false; // 无效句柄
    }

    // 遍历所有层级（0~3）
    for (int level = 0; level < 4; ++level) {
        // 遍历当前层级的所有槽位（0~255）
        for (int slot = 0; slot < 256; ++slot) {
            std::lock_guard<std::mutex> lock(wheels[level][slot].slotelock);
            auto& task_list = wheels[level][slot].slotelem;

            // 遍历槽位中的任务，查找匹配句柄
            for (auto it = task_list.begin(); it != task_list.end(); ++it) {
                if (it->handle == handle) {
                    // 找到并删除任务
                    task_list.erase(it);
                    return true; // 成功删除
                }
            }
        }
    }

    // 任务可能已到期并被提交到线程池（此时无法删除，返回失败）
    return false;
}

TimerHandle timers::addtimer(cb cbs, void *puser, uint32_t interval, bool repeat)
{
    if (cbs == nullptr) {
        return 0; // 错误码：无效回调
    }
    // 2. 校验重复任务的间隔不能为0（否则无限重添加）
    if (repeat && interval == 0) {
        return 0; // 错误码：重复任务间隔无效
    }
    TimerHandle handle = next_handle++;
    if (handle == 0) { // 防止溢出（理论上极难发生）
        handle = next_handle++; // 跳过0
    }
    uint32_t tt = _gettimeticket();
    uint32_t expire = interval + tt;
    int level = 0;
    int slot = 0;
    _calclevelandslot(interval, tt, level, slot);
    // 创建并初始化任务对象
    TimerElem tmp;
    tmp.handle = handle;
    tmp.callback = cbs;
    tmp.expire = expire;
    tmp.interval = interval;
    tmp.puser = puser;
    tmp.repeat = repeat;
    {
        std::lock_guard<std::mutex> lock(wheels[level][slot].slotelock);
        wheels[level][slot].slotelem.push_back(tmp);
    }
    return handle;
}

void timers::_process_cycle_tasks(list<TimerElem> &cycle_tasks)
{
    for (auto &task : cycle_tasks)
    {
        uint32_t current_tick = _gettimeticket();
        // 1. 轻量化计算：更新expire和新槽位
        task.expire = current_tick + task.interval;
        int new_level = 0, new_slot = 0;
        _calclevelandslot(task.interval, current_tick, new_level, new_slot);

        // 2. 头插目标槽位（独立锁，锁粒度小）
        {
            lock_guard<mutex> lock(wheels[new_level][new_slot].slotelock);
            wheels[new_level][new_slot].slotelem.push_front(std::move(task)); // 用move减少拷贝
        }
    }
}

void timers::tick()
{
    uint32_t tt = _gettimeticket();
    int slot = tt % 256;

    if ((tt != 0) && slot == 0)
    {
        uint32_t span = 1;
        for (int i = 1; i < 4; ++i)
        {
            span *= 256;
            int hslot = (tt / span) % 256;
            cascade(i, hslot);
            if (hslot != 0)
            {
                break;
            }
        }
    }
    std::list<TimerElem> listtmp;
    std::list<TimerElem> listrepeat;
    {
        std::lock_guard<std::mutex> lock(wheels[0][slot].slotelock);
        listtmp.splice(listtmp.end(), wheels[0][slot].slotelem);
    }
    for (auto p = listtmp.begin(); p != listtmp.end(); ++p)
    {
        if (p->repeat)
        {
            TimerElem t = *p;
            listrepeat.push_back(t);
        }
    }
    this->threadpool->submit_batch(listtmp);
    _process_cycle_tasks(listrepeat);
    _inctimeticket();
}

timers::timers(IThreadPoolPtr ptr)
{
    timeticket = 0;
    threadpool = ptr;
}

timers::~timers()
{
}

int main(int argc, char const *argv[])
{
    /* code */
    return 0;
}
